package com.zenchn.aspect.utils;

import com.zenchn.utils.ClassUtils;
import com.zenchn.utils.ObjectUtils;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import eu.bitwalker.useragentutils.Version;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/***
 * HttpServletRequest 相关数据处理工具类
 * @author panbingqi
 * @date 2021-06-01
 */
public class LogAspectUtils {

    private static final List<Class<?>>   INCLUDE_CLASS_LIST=new ArrayList<Class<?>>();


    static {
        INCLUDE_CLASS_LIST.addAll(ClassUtils.getClassList("com.zenchn.model"));
        INCLUDE_CLASS_LIST.addAll(ClassUtils.getClassList("com.zenchn.pojo"));
        INCLUDE_CLASS_LIST.addAll(ClassUtils.getClassList("com.zenchn.entity"));
    }

    /**
     * 获取组装 request请求中 header 中信息
     * @param request
     * @return
     */
    public static Map<String, String> getHeadersInfo(HttpServletRequest request){
        Map<String, String> map = new HashMap<>(16);
        Enumeration headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }



    /***
     * 获取组装  joinPoint.getArgs() 得到的数据
     * @param args
     * @return
     */
    public static List<Map<String, Object>> getArgs(Object[] args){
        List<Map<String, Object>> list=new ArrayList<>();
        for (Object arg:args){
            if (null!=arg && INCLUDE_CLASS_LIST.contains(arg.getClass())) {
                list.add(ObjectUtils.transNotNullBeanToMap(arg));
            }
        }
        return list;
    }


    /***
     * 通过request.getParameterMap()很轻松的获得参数Map，但得到的Map和普通Map是不一样的，是被锁定的，不能像操作常规Map那样进行put、get等操作，该方法将得到参数Map返回为可操作的普通Map
     * @param request
     * @return
     */
    public static Map getParameterMap(HttpServletRequest request) {
        // 参数Map
        Map properties = request.getParameterMap();
        // 返回值Map
        Map returnMap = new HashMap(16);
        Iterator entries = properties.entrySet().iterator();
        Map.Entry entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if(null == valueObj){
                value = "";
            }else if(valueObj instanceof String[]){
                String[] values = (String[])valueObj;
                for (String s : values) {
                    value = s + ",";
                }
                value = value.substring(0, value.length()-1);
            }else{
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }


    /**
     * 获取发起请求的浏览器名称
     */
    public static String getBrowserName(HttpServletRequest request) {
        String header = request.getHeader("User-Agent");
        UserAgent userAgent = UserAgent.parseUserAgentString(header);
        Browser browser = userAgent.getBrowser();
        return browser.getName();
    }

    /**
     * 获取发起请求的浏览器版本号
     */
    public static String getBrowserVersion(HttpServletRequest request) {
        String header = request.getHeader("User-Agent");
        UserAgent userAgent = UserAgent.parseUserAgentString(header);
        //获取浏览器信息
        Browser browser = userAgent.getBrowser();
        //获取浏览器版本号
        Version version = browser.getVersion(header);
        if(version == null){
            return null;
        }
        return version.getVersion();
    }

    /**
     * 获取发起请求的操作系统名称
     */
    public static String getOsName(HttpServletRequest request) {
        String header = request.getHeader("User-Agent");
        UserAgent userAgent = UserAgent.parseUserAgentString(header);
        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
        return operatingSystem.getName();
    }
}
